/**
 * @(#)UserAccount.java        1.0 2/15/12
 * 
 * Copyright (c) 2012 public static droid main
 * Georgia Institute of Technology, Atlanta, GA
 * All rights reserved.
 */

package edu.gatech.oad.publicstaticdroidmain.taskmanager.model;

import java.util.Date;

/**
 * Abstraction of an account in the TaskManager.  Allows for retrieval
 * and editing of user settings and interaction with a user's Tasks.
 * Also includes facilities for sorting and searching through a user's
 * Tasks.  To do this, two separate TaskLists are maintained: a master 
 * list containing all of a user's Tasks, and a filtered list containing a
 * subset of the master list.  The filtered list can be manipulated and
 * reset via the methods in this class.
 * 
 * @version 1.0 2/27/12
 * @author Daniel Hull
 *
 */
public class UserAccount {
	private String username;
	private String password;

	private String name;
	private String emailAddress;

	private TaskList masterTaskList;
	private TaskList filteredTaskList;

	/**
	 * Constructor, sets up the masterTaskList
	 * @param username the username
	 * @param password the password
	 * @param name the user's real name
	 * @param emailAddress the user's email address
	 */
	public UserAccount(String username, String password, String name, String emailAddress) {
		this.username = username;
		this.password = password;
		this.name = name;
		this.emailAddress = emailAddress;

		masterTaskList = new TaskList();
		filteredTaskList = masterTaskList;
	}

	/**
	 * adds a task to the master task list
	 * @param t the task
	 * @param category category the task goes under
	 */
	public void addTask(Task t, String category) {
		masterTaskList.add(category, t);
	}

	/**
	 * edits a task within master task list
	 * @param id the task's ID
	 * @param name new task name
	 * @param description new task description
	 * @param dueDate new task due date
	 * @param latitude new task latitude
	 * @param longitude new task longitude
	 * @param recurrence new task recurrence
	 * @param completionStatus the new completion status
	 * @return true if edited sucessfully else false
	 */
	public boolean editTask(long id, String name, String description, Date dueDate, double 
			latitude, double longitude, Task.Recurrence recurrence, boolean completionStatus) {

		boolean successfullyEdited = false;

		Task taskToEdit = masterTaskList.get(id);

		if (taskToEdit != null) {
			taskToEdit.setName(name);
			taskToEdit.setDescription(description);
			taskToEdit.setDueDate(dueDate);
			taskToEdit.setLatitude(latitude);
			taskToEdit.setLongitude(longitude);
			taskToEdit.setRecurrence(recurrence);
			taskToEdit.setCompleted(completionStatus);

			successfullyEdited = true;
		}

		return successfullyEdited;
	}

	/**
	 * removes a task from master task list
	 * 
	 * @param id task ID
	 * @return true if successful else false
	 */
	public boolean removeTask(long id) {
		return (masterTaskList.remove(id) != null);
	}

	/**
	 * returns the information of a task
	 * 
	 * @param id the ID of the task we desire
	 * @param attributes attributes of the task we desire
	 * @return array of task information
	 */
	public String[] getTaskData(long id, Task.TaskAttribute[] attributes) {
		return masterTaskList.getTaskData(id, attributes);
	}

	/**
	 * retrieves all the category names
	 * 
	 * @return array of category names
	 */
	public String[] getCategories() {
		return masterTaskList.getCategories();
	}

	/**
	 * adds a category to the masterTaskList
	 * 
	 * @param categoryName new category's name
	 * @return true if successful else false
	 */
	public boolean addCategory(String categoryName) {
		return masterTaskList.addCategory(categoryName);
	}

	/**
	 * edits a category name
	 * 
	 * @param oldName the old name of the category
	 * @param newName what we want the category to be named now
	 * @return  true if successful else false
	 */
	public boolean editCategoryName(String oldName, String newName) {
		return masterTaskList.editCategoryName(oldName, newName);
	}

	/**
	 * removes a category from the masterTaskList
	 * 
	 * @param categoryName the name of the category to be removed
	 * @return the name of the removed category
	 */
	public String removeCategory(String categoryName) {
		return masterTaskList.removeCategory(categoryName);
	}

	/**
	 * returns the information of all the tasks in an account
	 * 
	 * @param attributes attributes of tasks
	 * @return 2d array of task information
	 */
	public Object[] getMasterListDisplayData() {
		return masterTaskList.toArray();
	}

	/**
	 * retrieves only the data with specified attributes
	 * 
	 * @param attributes attributes of desired data
	 * @return 2d array of task data
	 */
	public String[][] getFilteredListDisplayData(Task.TaskAttribute[] attributes) {
		return filteredTaskList.to2DArray(attributes);
	}

	/**
	 * Filters out the tasks not under the specified category
	 * 
	 * @param category name of desired category
	 */    
	public void filterByCategory(String category) {
		filteredTaskList = filteredTaskList.filterByCategory(category);
	}

	/**
	 * filters out any information not within the desired time period
	 * 
	 * @param start beginning of time period
	 * @param end end of time period
	 */
	public void filterByDueDate(Date start, Date end) {
		filteredTaskList = filteredTaskList.filterByDueDate(start, end);
	}

	/**
	 * filters out any tasks that don't have the specified recurrence
	 * 
	 * @param recurrence desired recurrence of the tasks
	 */
	public void filterByRecurrence(Task.Recurrence recurrence) {
		filteredTaskList = filteredTaskList.filterByRecurrence(recurrence);
	}

	/**
	 * filters by location
	 * 
	 * @param startLatitude
	 * @param endLatitude
	 */
	public void filterByLatitude(double startLatitude, double endLatitude) {
		filteredTaskList = filteredTaskList.filterByLatitude(startLatitude, endLatitude);
	}

	/**
	 * filters by location
	 * 
	 * @param startLongitude
	 * @param endLongitude
	 */
	public void filterByLongitude(double startLongitude, double endLongitude) {
		filteredTaskList = filteredTaskList.filterByLongitude(startLongitude, endLongitude);
	}

	/**
	 * filters by completion status
	 * 
	 * @param completionStatus
	 */
	public void filterByCompletionStatus(boolean completionStatus) {
		filteredTaskList = filteredTaskList.filterByCompletionStatus(completionStatus);
	}

	/**
	 * searches for a task with a certain name
	 * 
	 * @param text the desired task's name
	 */
	public void searchTaskNames(String text) {
		filteredTaskList = filteredTaskList.searchTaskNames(text);
	}

	/**
	 * searches for a task with a certain description
	 * 
	 * @param text the desired task's description
	 */
	public void searchTaskDescriptions(String text) {
		filteredTaskList = filteredTaskList.searchTaskDescriptions(text);
	}

	/**
	 * resets the list of tasks within account to a full list of tasks 
	 * 
	 */
	public void resetFilteredList() {
		filteredTaskList = masterTaskList;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the emailAddress
	 */
	public String getEmailAddress() {
		return emailAddress;
	}

	/**
	 * @param emailAddress the emailAddress to set
	 */
	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}


	public boolean equals(Object other) {
		if (other == null) {
			return false;
		}

		if (other.getClass() != this.getClass()) {
			return false;
		}

		UserAccount otherAccount = (UserAccount) other;

		if (!this.username.equals(otherAccount.username)) {
			return false;
		}

		if (!this.password.equals(otherAccount.password)) {
			return false;
		}

		if (!this.name.equals(otherAccount.name)) {
			return false;
		}

		if (!this.emailAddress.equals(otherAccount.emailAddress)) {
			return false;
		}

		if (!this.masterTaskList.equals(otherAccount.masterTaskList)) {
			return false;
		}

		if (!this.filteredTaskList.equals(otherAccount.filteredTaskList)) {
			return false;
		}

		return true;
	}

	public String toString() {
		StringBuffer stringRep = new StringBuffer();

		stringRep.append("Username: " + username + "\n");
		stringRep.append("Password: " + password + "\n");
		stringRep.append("Name: " + name + "\n");
		stringRep.append("Email Address: " + emailAddress);

		return stringRep.toString();
	}

}
